package com.mo.xi.ge.info.bean

import android.Manifest
import android.app.ActivityManager
import android.app.ActivityManager.MemoryInfo
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import android.os.Build
import android.os.Environment
import android.os.StatFs
import android.os.SystemClock
import android.provider.Settings
import android.telephony.TelephonyManager
import com.google.gson.JsonObject
import com.mo.xi.ge.info.help.DeviceCheckUUtil
import com.mo.xi.ge.info.help.DeviceInfoUtil
import com.mo.xi.ge.info.help.DeviceNetUtil
import com.mo.xi.ge.info.help.EntryInfoManager
import com.mo.xi.ge.info.help.checkAppPermission
import com.mo.xi.ge.info.help.infoTryCatch
import com.mo.xi.ge.info.help.toIntValue
import java.util.Locale

/**
 * date:2024/1/25
 **/
internal class SystemInfo {

    // 获取硬件信息
    fun getHardInfo(context: Context): JsonObject {
        try {
            return JsonObject().also {
                val displayMetrics = context.resources.displayMetrics
                it.addProperty("width_extent", "${displayMetrics.widthPixels}") //设备屏幕宽度
                it.addProperty("height_extent", "${displayMetrics.heightPixels}") //设备屏幕高度
                it.addProperty("brand_info_data", Build.BRAND) //品牌
                it.addProperty("board_metric", Build.BOARD)//主板
                it.addProperty("core_record", Runtime.getRuntime().availableProcessors()) //cpu核心数量
                it.addProperty("release_metric", Build.VERSION.RELEASE) // 系统版本
                it.addProperty("model_label", Build.MODEL) //手机型号 Build.MODEL
                it.addProperty("device_record", "")
                try {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
                        it.addProperty(
                            "device_record", Settings.Secure.getString(
                                context.contentResolver, Settings.Global.DEVICE_NAME
                            ).orEmpty()
                        )
                    } else {
                        it.addProperty(
                            "device_record",
                            Settings.Global.getString(context.contentResolver, "device_name")
                        )
                    }
                } catch (e: Exception) {
                } //Settings.Global.DEVICE_NAME
                it.addProperty("sdk_metrics", "${Build.VERSION.SDK_INT}") //系統api版本,如33
            }
        } catch (e: Exception) {
            return JsonObject()
        }
    }

    // 获取设备信息
    fun getDevicInfo(context: Context): JsonObject {
        val jobj = JsonObject()
        jobj.addProperty("update_time_in_ms", SystemClock.uptimeMillis()) // 自启动以来的毫秒级非睡眠正常运行时间。
        jobj.addProperty(
            "boot_time_info", System.currentTimeMillis() - SystemClock.elapsedRealtime() / 1000000L
        ) //当前开机的时间(currentMiles -elapsedRealtime/1000000L )
        jobj.addProperty("real_time_info", SystemClock.elapsedRealtime())
        // 网络类型

        if (context.checkAppPermission(Manifest.permission.ACCESS_NETWORK_STATE)) {
            jobj.addProperty(
                "network_sort",
                infoTryCatch("") { DeviceNetUtil.getNetworkType(context) })
        } else {
            jobj.addProperty("network_sort", "")
        }
        jobj.addProperty("simulator_record", DeviceCheckUUtil.deviceEmulator(context)) // 是否为模拟器
        jobj.addProperty("android_id_number", DeviceInfoUtil.getAndroidId(context)) // android id
        jobj.addProperty("iso3_country_number",
            infoTryCatch("") { Locale.getDefault().isO3Country.orEmpty() })
        jobj.addProperty("regional_display_language",
            infoTryCatch("") { Locale.getDefault().displayLanguage.orEmpty() })
        jobj.addProperty(
            "iso3_language_number",
            infoTryCatch("") { Locale.getDefault().isO3Language.orEmpty() })
        jobj.addProperty("deviceAlias", EntryInfoManager.getDeviceNickName(context))
        jobj.addProperty("rights_management_id", EntryInfoManager.mDalaDramId)
        jobj.addProperty("debug_usb", DeviceInfoUtil.isUsbDebug(context))
        jobj.addProperty("airpl_funct", DeviceInfoUtil.isAirModeOn(context).toIntValue())
        jobj.addProperty("mobile_network_quality", DeviceInfoUtil.getMobileDbm(context))
        jobj.addProperty(
            "device_bluetooth_name",
            DeviceInfoUtil.getBluetoothName(context).orEmpty()
        ) // 蓝牙
        jobj.addProperty("fake_location", DeviceInfoUtil.isMockLocaEnable(context)) // 模拟定位
        jobj.addProperty(
            "enabled_accessibility",
            DeviceCheckUUtil.isAccessEnabled(context).toIntValue().toString()
        ) // 模拟定位
        jobj.addProperty(
            "enable_data_roaming", DeviceInfoUtil.isDataRoaming(context).toIntValue().toString()
        ) // 数据漫游
        jobj.addProperty(
            "default_method", DeviceInfoUtil.getDefInput(context)
        ) // 默认输入法
        jobj.addProperty(
            "enabled_touch_exploration",
            DeviceInfoUtil.isTouchExplorEnable(context).toIntValue().toString()
        ) // 触摸检测
        jobj.addProperty(
            "enabled_development_settings",
            DeviceInfoUtil.isDevelop(context).toIntValue().toString()
        ) // 开发者模式
        jobj.addProperty(
            "timeout_screen_off", DeviceInfoUtil.getScreenTime(context).toString()
        ) // 屏幕时间
        return jobj
    }

    fun getBytterInfo(context: Context): JsonObject {
        val battMg = try {
            context.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
        } catch (e: Exception) {
            null
        }
        val battIntent = getBatteryIntent(context)
        val battryLevel = battMg?.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY) ?: -1
        val battryMax = getTotalBattery(context)
        val battryNow = battryMax * battryLevel / 100

        val batteryObj = JsonObject()
        batteryObj.addProperty("max_battery", battryMax) //电池总量
        batteryObj.addProperty("present_battery_capacity", battryNow) //当前剩余电量

        batteryObj.addProperty("left_time", getBatteryLeft(battMg)) //充电剩余
        batteryObj.addProperty("battery_status", getLeftBattery(context)) //电量百分比

        batteryObj.addProperty(
            "bater_po_rdtion",
            battMg?.getIntProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW) ?: -1
        ) //实时耗电,正值表示从充电源进入电池的净电流，负值表示从电池放电的净电流
        batteryObj.addProperty("insertion", getTypeInfo(battIntent, BatteryManager.EXTRA_PLUGGED)) //电源信息
        batteryObj.addProperty("battery_wellbeing", getTypeInfo(battIntent, BatteryManager.EXTRA_HEALTH)) //电池健康度

        var status = -1
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            status = battMg?.getIntProperty(BatteryManager.BATTERY_PROPERTY_STATUS) ?: -1
        }
        if (status == -1) {
            status = getTypeInfo(battIntent, BatteryManager.EXTRA_STATUS)
        }
        batteryObj.addProperty("status_code", status) //电池状态
        batteryObj.addProperty(
            "battery_warmth", getTypeInfo(battIntent, BatteryManager.EXTRA_TEMPERATURE)
        ) //温度
        batteryObj.addProperty(
            "voltage_power", getTypeInfo(battIntent, BatteryManager.EXTRA_VOLTAGE)
        ) //电池电压
        batteryObj.addProperty(
            "battery_magnitude", getTypeInfo(battIntent, BatteryManager.EXTRA_SCALE)
        ) //最大电池电量
        batteryObj.addProperty(
            "battery_representation", getTypeInfo(battIntent, BatteryManager.EXTRA_ICON_SMALL)
        ) //电量图标资源id
        batteryObj.addProperty(
            "battery_charge_count", getTypeInfo(battIntent, Intent.ACTION_BATTERY_CHANGED)
        ) //剩余电量，单位 (mAH)微安小时
        batteryObj.addProperty(
            "at_hand", battIntent?.getBooleanExtra(BatteryManager.EXTRA_PRESENT, false) ?: false
        ) //是否存在电池
        batteryObj.addProperty("renewing", isDeviceCharging(battIntent)) //是否充电
        batteryObj.addProperty(
            "mechanism", battIntent?.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY).orEmpty()
        ) //电池技术
        return batteryObj
    }

    private fun getTypeInfo(intent: Intent?, type: String) = try {
        intent?.getIntExtra(type, -1) ?: -1
    } catch (e: Exception) {
        -1
    }

    private fun getBatteryLeft(battmg: BatteryManager?): Long {
        var def = -1024L
        try {
            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
                battmg?.let {
                    def = it.computeChargeTimeRemaining()
                }
            }
        } catch (e: Exception) {
        }
        return def
    }

    // 获取电池总容量
    private fun getTotalBattery(context: Context): Double {
        var result = 0.0
        try {
            val profileClass = "com.android.internal.os.PowerProfile"
            val mPowerProfile =
                Class.forName(profileClass).getConstructor(Context::class.java)
                    .newInstance(context)
            result = Class.forName(profileClass).getMethod("getBatteryCapacity")
                .invoke(mPowerProfile) as Double
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return result
    }

    private fun getLeftBattery(context: Context): Int {
        return try {
            val intent = getBatteryIntent(context)
            intent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) ?: -1
        } catch (e: Exception) {
            -1
        }
    }

    private fun getBatteryIntent(context: Context): Intent? {
        val intentFilter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        var intent: Intent? = null
        try {
            intent = context.registerReceiver(null, intentFilter)
        } catch (e: Exception) {
        }
        return intent
    }

//    private fun getCurr(battmg: BatteryManager?): Float {
//        return try {
//            (battmg?.getIntProperty(BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER) ?: -1) * 1f
//        } catch (e: Exception) {
//            -1f
//        }
//    }

    private fun isDeviceCharging(intent: Intent?): Boolean {
        return try {
            val status = intent?.getIntExtra(BatteryManager.EXTRA_STATUS, -1) ?: -1
            val isStatus =
                status == BatteryManager.BATTERY_STATUS_CHARGING || BatteryManager.BATTERY_STATUS_FULL == status
            isStatus
        } catch (e: Exception) {
            false
        }
    }

    class DeviceMemoryInfo {

        fun getMemoryInfo(context: Context): JsonObject {
            val memoryObj = JsonObject()
            getMemory1(memoryObj, context)
            getMemory2(memoryObj)

            memoryObj.addProperty(
                "external_memory_inside",
                hasDevicesExternal().toIntValue()
            )//是否拥有sd卡槽(0,1)
            memoryObj.addProperty("sd_supplementary", checkDeviceSdk(context).toIntValue())//是否存在sdk卡(0,1)
            return memoryObj
        }

        private fun getMemory2(memoryObj: JsonObject) {
            memoryObj.addProperty("usable_capacity", tryCatch {
                val path = Environment.getDataDirectory()
                val stat = StatFs(path.absolutePath)
                stat.availableBlocksLong * stat.blockSizeLong
            })//内置内存使用大小
            memoryObj.addProperty("sum_storage", tryCatch {
                val path = Environment.getDataDirectory()
                val stat = StatFs(path.absolutePath)
                stat.blockSizeLong * stat.blockCountLong
            })//内置内存总大小
            memoryObj.addProperty("size_memory_card", getExternalCacheSize())//外部存储总大小
            memoryObj.addProperty("unused_card_memory", tryCatch {
                val path = Environment.getExternalStorageDirectory().absolutePath
                val statfs = StatFs(path)
                statfs.blockSizeLong * statfs.availableBlocksLong
            })//外部存储总可用大小
            memoryObj.addProperty("usable_capacity_card", tryCatch {
                val path = Environment.getExternalStorageDirectory().absolutePath
                val statfs = StatFs(path)
                statfs.blockSizeLong * statfs.blockCountLong
            })//外部存储空闲且可以大小
            memoryObj.addProperty("used_card_capacity", tryCatch {
                val path = Environment.getExternalStorageDirectory().absolutePath
                val statfs = StatFs(path)
                statfs.blockSizeLong * statfs.availableBlocksLong
            })//外部存储已用大小
        }

        private fun getMemory1(memoryObj: JsonObject, context: Context) {
            memoryObj.addProperty("memory_cap", tryCatch {
                Runtime.getRuntime().maxMemory()
            })//虚拟机最大内存量
            memoryObj.addProperty("idle_memory",
                tryCatch { Runtime.getRuntime().freeMemory() })//虚拟机可用内存量
            memoryObj.addProperty("sum_memory", tryCatch {
                Runtime.getRuntime().totalMemory()
            })//虚拟机内存总量
            memoryObj.addProperty("sum_ram", getRamTotalSize(context))//设备的ram大小，内核可访问的总内存。
            memoryObj.addProperty("usable_capacy", tryCatch {
                val ams = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val meiinfo = MemoryInfo()
                ams.getMemoryInfo(meiinfo)
                meiinfo.availMem
            })//ram可用内存
        }

        // 外部存储大小
        private fun getExternalCacheSize(): Long {
            return tryCatch {
                val path = Environment.getExternalStorageDirectory().absolutePath
                val statfs = StatFs(path)
                statfs.blockSizeLong * statfs.blockCountLong
            }
        }

        private fun checkDeviceSdk(context: Context): Boolean {
            return try {
                val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
                tm.hasIccCard()
            } catch (e: Exception) {
                false
            }
        }

        private fun hasDevicesExternal(): Boolean {
            return try {
                Environment.getExternalStorageState() == Environment.MEDIA_MOUNTED
            } catch (e: Exception) {
                false
            }
        }

        private fun getRamTotalSize(context: Context): Long {
            return tryCatch {
                val ams = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
                val meiinfo = MemoryInfo()
                ams.getMemoryInfo(meiinfo)
                meiinfo.totalMem
            }
        }

        private fun tryCatch(block: () -> Long): Long {
            return try {
                block()
            } catch (e: Exception) {
                -1L
            }
        }
    }
}
